using System;
using System.Collections;
using System.Web;
using System.Web.Caching;

using Azure.Domain.Models;
using Azure.Web;
using Xunit;

namespace Azure.Tests.Web
{
    public class CacheServiceFacts : Facts<CacheService<Post>>
    {
        public CacheServiceFacts()
        {
            foreach (DictionaryEntry cacheItem in HttpRuntime.Cache)
            {
                HttpRuntime.Cache.Remove((string) cacheItem.Key);
            }
        }

        [Fact]
        public void AddWillAddANewItemToCache()
        {
            var post = Test.Post;
            var key = ClassUnderTest.GetKey(post);
            ClassUnderTest.Add(post);
            HttpRuntime.Cache.Remove(key);

            ClassUnderTest.Add(post);

            var item = (Post) HttpRuntime.Cache.Get(key);

            Assert.Equal(post.PartitionKey, item.PartitionKey);
            Assert.Equal(post.RowKey, item.RowKey);
        }

        [Fact]
        public void AddWillUpdateAnItemAlreadyInCache()
        {
            var post = Test.Post;
            var key = ClassUnderTest.GetKey(post);
            ClassUnderTest.Add(post);
            HttpRuntime.Cache.Add(key, post, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration,
                                  CacheItemPriority.Normal, null);

            post.Title = "New Title";
            ClassUnderTest.Add(post);

            var item = (Post)HttpRuntime.Cache.Get(key);

            Assert.Equal(post.PartitionKey, item.PartitionKey);
            Assert.Equal(post.RowKey, item.RowKey);
            Assert.Equal("New Title", item.Title);
        }

        [Fact]
        public void CachePersistsLastPost()
        {
            var originalPost = Test.Post;
            ClassUnderTest.Latest = originalPost;

            Assert.Equal(originalPost, ClassUnderTest.Latest);
        }

        [Fact]
        public void GetReturnsNullIfNothingIsLoaded()
        {
            var post = Test.Post;
            post = ClassUnderTest.Get(post.PartitionKey, post.RowKey);

            Assert.Null(post);
        }

        [Fact]
        public void GetReturnsTheObjectIfItIsInCache()
        {
            var post = Test.Post;
            var key = ClassUnderTest.GetKey(post);
            HttpRuntime.Cache.Add(key, post, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);

            var item = ClassUnderTest.Get(post.PartitionKey, post.RowKey);

            Assert.NotNull(item);
        }

        [Fact]
        public void KeyGeneratorWorksAsExpected()
        {
            var post = Test.Post;
            post.PartitionKey = "12345678";
            post.RowKey = "HellO-WorLD";

            var result = ClassUnderTest.GetKey(post);

            Assert.Equal("12345678hello-world", result);
        }
    }
}